package task_record

import (
	rich_err "app/error"
	"app/models"
	"app/service"
	"app/utils"
	"errors"
	"math"

	"github.com/jinzhu/gorm"

	"github.com/gin-gonic/gin"
)

func Gets(context *gin.Context) ([]*models.TaskRecord, *models.Pager, *rich_err.RichError) {
	base := models.Orm.Model(&models.TaskRecord{}).
		Select("task_record.*")
	results, pager, err := service.GetDetails[models.TaskRecord](context, base, models.TaskRecord{}.TableName(), map[string]string{})
	if err != nil {
		return nil, nil, rich_err.NewError(rich_err.RequestInvalid, err)
	}
	return results, pager, nil
}

func Get(context *gin.Context) (*models.TaskRecord, *rich_err.RichError) {
	data, err := service.Get[models.TaskRecord](context)
	if err != nil {
		return nil, rich_err.NewError(rich_err.RequestInvalid, err)
	}
	return data, nil
}

func Create(context *gin.Context) (*models.TaskRecord, *rich_err.RichError) {
	req := new(models.TaskRecordCore)
	if err := context.ShouldBindJSON(req); err != nil {
		return nil, rich_err.NewError(rich_err.RequestInvalid, err)
	}
	data := models.TaskRecord{TaskRecordCore: *req}
	if data.OSSUrl != "" {
		accessURL, err := utils.GetOSSUrl(data.OSSUrl)
		if err == nil && accessURL != "" {
			data.AccessUrl = accessURL
		}
	}
	result := models.Orm.Create(&data)
	if result.Error != nil {
		return nil, rich_err.NewError(rich_err.DatabaseFailed, result.Error)
	}
	return &data, nil
}

func Update(context *gin.Context) (*models.TaskRecord, *rich_err.RichError) {
	req := new(models.TaskRecordDelta)
	if err := context.ShouldBindJSON(req); err != nil {
		return nil, rich_err.NewError(rich_err.RequestInvalid, err)
	}

	data, err := service.Get[models.TaskRecord](context)
	if err != nil {
		return nil, rich_err.NewError(rich_err.RequestInvalid, err)
	}
	if req.Name != nil {
		data.Name = req.Name.(string)
	}

	if req.Variant != nil {
		data.Variant = req.Variant.(string)
	}

	if req.Quantity != nil {
		data.Quantity = req.Quantity.(string)
	}

	if req.DriverName != nil {
		data.DriverName = req.DriverName.(string)
	}
	if req.DriverPhone != nil {
		data.DriverPhone = req.DriverPhone.(string)
	}

	if req.TaskDate != nil {
		data.TaskDate = utils.ToDateV2(req.TaskDate.(string))
	}

	if req.Status != nil {
		data.Status = int(math.Round(req.Status.(float64)))
	}

	if req.Remark != nil {
		data.Remark = req.Remark.(string)
	}
	if req.OSSUrl != nil && req.OSSUrl.(string) != data.OSSUrl {
		data.OSSUrl = req.OSSUrl.(string)
		accessURL, err := utils.GetOSSUrl(data.OSSUrl)
		if err == nil && accessURL != "" {
			data.AccessUrl = accessURL
		}
	}
	result := models.Orm.Save(data)
	if result.Error != nil {
		return nil, rich_err.NewError(rich_err.DatabaseFailed, result.Error)
	}
	return data, nil
}

func Delete(context *gin.Context) *rich_err.RichError {
	data, err := service.Get[models.TaskRecord](context)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil
		}
		return rich_err.NewError(rich_err.RequestInvalid, err)
	}
	result := models.Orm.Delete(data)
	if result.Error != nil {
		return rich_err.NewError(rich_err.DatabaseFailed, result.Error)
	}
	return nil
}
